﻿using SuperX.Common.Abstract;
using SuperX.Common;
using SuperX.DataService;
using SuperX.DataService.Abstract;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Net;
using SuperX.Common.Object;
using SuperX.Helper;
using SuperX.Common.BasicService;
using SuperX.Common.Collection;
using Newtonsoft.Json;
using System.IO;
using System.Text;
using SuperX.Common.Log;
using System.Threading;
using SuperX.Common.MSG;
using System.ComponentModel;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using SuperX.DataService.Helper;
using System.Security.Cryptography.X509Certificates;

namespace SuperX.DataService
{
    /// <summary>
    /// 虚拟设备系统地址需实现GetDefaultConfig静态方法
    /// </summary>
    public abstract class AnalysisDriverBase : DriverBase, IVirtualDriver
    {
        public AnalysisDeviceGroup Group;

        public List<AnalysisBase> Processeds = new List<AnalysisBase>();

        [JsonIgnore]
        public List<FileAnalysisConfig> FileAnalysis { get; set; }

        /// <summary>
        /// 设备类型
        /// </summary>
        public abstract DeviceTypeInfo DriverInfo { get; }

        public string MesId { get; set; }

        public override bool IsClosed
        {
            get => fileAnalysisClose;
        }

        protected bool fileAnalysisClose;

        protected IDataServer _parent;

        public AnalysisDriverBase(IDataServer parent, string name, string nodeName)
        {
            Name = name;
            NodeKey = nodeName;
            _parent = parent;
            this.Parent = parent;
            _server = parent;
            fileAnalysisClose = true;
        }

        public AnalysisDriverBase()
        {
        }

        public virtual bool Init()
        {
            SetProcessed();
            Processeds.ForEach(p =>
            {
                p.Init();
            });
            return true;
        }

        public override bool Connect()
        {
            Processeds.ForEach(p =>
            {
                p.Start();
            });
            fileAnalysisClose = false;
            return false;
        }

        public override void Dispose()
        {
            Processeds.ForEach(p =>
            {
                p.Stop();
            });
            foreach (var group in DriverGroup)
            {
                group.Dispose();
            }
            DriverGroup.Clear();
            base.Dispose();
        }

        public abstract void SetProcessed();

        public override IGroup AddGroup(string name, int updateRate, float deadBand = 0, bool active = false)
        {
            AnalysisDeviceGroup group = new AnalysisDeviceGroup(name, updateRate, active, this);
            DriverGroup.Add(group);
            return group;
        }

        public override List<string> GetKeys()
        {
            return DriverGroup.Keys.ToList();
        }

        public override List<IBasicObject> GetValues()
        {
            var group = DriverGroup.Values?.OfType<IBasicObject>().ToList();
            return group;
        }

        public override bool IsUniqueName(string name, IObjCollection parent)
        {
            if (parent != null)
            {
                return parent.IsUniqueName(name, null);
            }

            return DriverGroup[name] == null;
        }

        public abstract bool ExecuteControlCmd(int index, bool bit);

        public override ItemData<dynamic> ReadDynamic(DeviceAddress address)
        {
            var tag = _parent.IndexFind((short)address.CacheIndex);
            return tag == null ? new ItemData<dynamic>(false, 0, QUALITIES.NG) : new ItemData<dynamic>(tag.Value, 0, QUALITIES.OK);
        }

        public int WriteValue(DeviceAddress address, object value)
        {
            if (!value.ObjToBool()) return -1;
            if (ExecuteControlCmd(address.Start + 1, value.ObjToBool())) return 0;
            else return -1;
        }

        #region 暂时用不到

        public byte[] ReadBytes(DeviceAddress address, ushort size)
        {
            return null;
        }

        public ItemData<int> ReadInt32(DeviceAddress address)
        {
            return new ItemData<int>(0, 0, QUALITIES.OK);
        }

        public ItemData<uint> ReadUInt32(DeviceAddress address)
        {
            return new ItemData<uint>(0, 0, QUALITIES.OK);
        }

        public ItemData<ushort> ReadUInt16(DeviceAddress address)
        {
            return new ItemData<ushort>(0, 0, QUALITIES.OK);
        }

        public ItemData<short> ReadInt16(DeviceAddress address)
        {
            return new ItemData<short>(0, 0, QUALITIES.OK);
        }

        public ItemData<byte> ReadByte(DeviceAddress address)
        {
            return new ItemData<byte>(0, 0, QUALITIES.OK);
        }

        public ItemData<string> ReadString(DeviceAddress address, ushort size)
        {
            return new ItemData<string>("", 0, QUALITIES.OK);
        }

        public ItemData<float> ReadFloat(DeviceAddress address)
        {
            return new ItemData<float>(0, 0, QUALITIES.OK);
        }

        public ItemData<bool> ReadBit(DeviceAddress address)
        {
            return new ItemData<bool>(false, 0, QUALITIES.OK);
        }

        public int WriteBytes(DeviceAddress address, byte[] bit)
        {
            return 0;
        }

        public virtual int WriteBits(DeviceAddress address, byte bits)
        {
            var tag = _parent.IndexFind((short)address.CacheIndex) as ByteTag;
            if (tag != null)
            {
                return tag.Write(bits);
            }
            return -1;
        }

        public int WriteInt16(DeviceAddress address, short value)
        {
            var tag = _parent.IndexFind((short)address.CacheIndex) as ShortTag;
            if (tag != null)
            {
                return tag.Write(value);
            }
            return -1;
        }

        public int WriteUInt16(DeviceAddress address, ushort value)
        {
            var tag = _parent.IndexFind((short)address.CacheIndex) as UShortTag;
            if (tag != null)
            {
                return tag.Write(value);
            }
            return -1;
        }

        public int WriteUInt32(DeviceAddress address, uint value)
        {
            var tag = _parent.IndexFind((short)address.CacheIndex) as UIntTag;
            if (tag != null)
            {
                return tag.Write(value);
            }
            return -1;
        }

        public int WriteInt32(DeviceAddress address, int value)
        {
            var tag = _parent.IndexFind((short)address.CacheIndex) as IntTag;
            if (tag != null)
            {
                return tag.Write(value);
            }
            return -1;
        }

        public int WriteFloat(DeviceAddress address, float value)
        {
            var tag = _parent.IndexFind((short)address.CacheIndex) as FloatTag;
            if (tag != null)
            {
                return tag.Write(value);
            }
            return -1;
        }

        public int WriteString(DeviceAddress address, string str)
        {
            return 0;
        }

        public int WriteBit(DeviceAddress address, bool bit)
        {
            return 0;
        }

        public bool[] ReadBools(DeviceAddress address, ushort size)
        {
            throw new NotImplementedException();
        }

        public void UpdateIOTag(string groupName)
        {
            throw new NotImplementedException();
        }

        public int WriteDynamic(IIOTag tag, object value)
        {
            throw new NotImplementedException();
        }

        #endregion 暂时用不到
    }

    public enum SortMethod
    {
        Name,
        Time
    }

    /// <summary>
    /// 设备信息
    /// </summary>
    public class DeviceTypeInfo
    {
        public DeviceTypeInfo(DeviceType typeName, Enum manufacturer)
        {
            _typeName = typeName;
            _manufacturer = manufacturer;
        }

        /// <summary>
        /// 类型名称
        /// </summary>
        public string TypeName
        { get { return _typeName.ToString(); } }

        private DeviceType _typeName;

        /// <summary>
        /// 制造商名称
        /// </summary>
        public string Manufacturer
        { get { return _manufacturer.ToString(); } }

        private Enum _manufacturer;
    }

    public enum DeviceType
    {
        /// <summary>
        /// 未识别
        /// </summary>
        UnRecognized,

        /// <summary>
        /// 贴片机
        /// </summary>
        Mountor,

        /// <summary>
        /// AOI
        /// </summary>
        Aoi,

        /// <summary>
        /// SPI
        /// </summary>
        Spi,

        /// <summary>
        /// ICT
        /// </summary>
        Ict,

        /// <summary>
        /// FCT
        /// </summary>
        Fct,

        /// <summary>
        /// 装片机(固晶机)
        /// </summary>
        DieBonder,

        /// <summary>
        /// 分割机
        /// </summary>
        Routing,

        /// <summary>
        /// 波峰焊
        /// </summary>
        WaveSoldering,

        /// <summary>
        /// 印刷机
        /// </summary>
        Printing,

        /// <summary>
        /// 真空炉
        /// </summary>
        VacuumOven
    }

    public enum MountorManufacturer
    {
        /// <summary>
        /// 未识别
        /// </summary>
        UnRecognized,

        /// <summary>
        /// 雅马哈
        /// </summary>
        Yamaha,

        /// <summary>
        /// 松下
        /// </summary>
        Panasossnic,

        /// <summary>
        /// JUKI
        /// </summary>
        Juki,

        /// <summary>
        /// 三星
        /// </summary>
        Samsung,

        /// <summary>
        /// 億立
        /// </summary>
        EM,

        /// <summary>
        /// 志勝威
        /// </summary>
        ZSW,

        /// <summary>
        /// 彼勒豪斯
        /// </summary>
        Pillarhouse,

        /// <summary>
        /// JutZe
        /// </summary>
        JutZe,

        /// <summary>
        /// DEK
        /// </summary>
        DEK
    }

    public enum AoiManufacturer
    {
        /// <summary>
        /// 未识别
        /// </summary>
        UnRecognized,

        /// <summary>
        /// 捷智
        /// </summary>
        Jet,

        /// <summary>
        /// 矩子
        /// </summary>
        Jutze,

        /// <summary>
        /// 赫立
        /// </summary>
        Holly,

        /// <summary>
        /// 明锐
        /// </summary>
        MagicRay,

        /// <summary>
        /// 新益昌
        /// </summary>
        HOSON
    }

    public enum SpiManufacturer
    {
        /// <summary>
        /// 未识别
        /// </summary>
        UnRecognized,

        /// <summary>
        /// 捷智
        /// </summary>
        Jet,

        /// <summary>
        /// 斯泰克
        /// </summary>
        SinicTek
    }

    public enum IctManufacturer
    {
        /// <summary>
        /// 未识别
        /// </summary>
        UnRecognized,

        /// <summary>
        /// 捷律
        /// </summary>
        Tri
    }

    public enum FctManufacturer
    {
        /// <summary>
        /// 未识别
        /// </summary>
        UnRecognized,

        /// <summary>
        /// 四湖创科技
        /// </summary>
        SHC
    }
}